fix(webex-core): re-evaluate credentials on app level redirects - #5150
Draft
chrisadubois wants to merge 1 commit into
Draft
fix(webex-core): re-evaluate credentials on app level redirects#5150chrisadubois wants to merge 1 commit into
chrisadubois wants to merge 1 commit into
Conversation
Copy the headers when re-issuing a request against a uri taken from the previous response, and drop the authorization header inherited from the previous request, so AuthInterceptor makes its normal decision against the new uri instead of returning early. Applies to all three redirect branches. Also require the documented 404 status code on the two body based branches, matching the status HttpStatusInterceptor already pairs with each of the two error codes. Ref: FPV-747 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
chrisadubois
marked this pull request as draft
August 5, 2026 23:23
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
COMPLETES #https://jira-eng-gpk2.cisco.com/jira/browse/FPV-747
This pull request addresses
RedirectInterceptor.onResponse()re-issues a request against a uri taken from the previous response. It copied the request options with lodashclone(), which is shallow, so the re-issued request kept the sameheadersobject as the request it replaced.AuthInterceptor.onRequest()returns early when a request already carries anauthorizationheader. A carried-over header therefore meantrequiresCredentials()never ran on the re-issued request, so neither the service catalog nor the allowed-domain list was evaluated against the uri that was about to be requested. All three redirect branches were affected: thecisco-locationresponse header, the LocuserrorCodebody, and the AppAPIcode/siteFullUrlbody.Separately, the two body-based branches keyed only off the response body and not off its status code, so they could act on a response that is not a redirect.
This is a different mechanism from #5144. That change made the allowed-domain comparison exact; this one is about that check not being reached. Neither fixes the other.
by making the following changes
All three branches now copy
headersas well, and drop theauthorizationinherited from the previous request, through a single shared helper:AuthInterceptorthen makes its normal decision against the uri that is actually about to be requested — the catalog lookup and the allowed-domain check both run — instead of returning early. Switchingclone()tocloneDeep()would not have been sufficient: it copies the header through unchanged.The two body-based branches additionally require the
404they are documented to arrive with. This is the same statusHttpStatusInterceptoralready pairs with each of the two error codes.The existing
preJoin/webex-appapi-servicecase still setsauthorization: falseexplicitly, so that request stays unauthenticated —AuthInterceptortreats a falsy value as "delete it and do not add one".Compatibility
Legitimate redirects continue to be authorized. Their targets are Locus hosts under
wbx2.comand Webex sites underwebex.com, both of which are inCOMMERCIAL_ALLOWED_DOMAINS. Foreign-cluster Locus hosts are additionally present in the service catalog, because_formatReceivedHostmap()collects every host that shares a service id, including those withhomeCluster: false, andfindServiceUrlFromUrl()matches against all of them. The same holds for FedRAMP, the narrowest allowlist, whose catalog and allowed domains are both gov hosts. On a legitimate redirect the header is re-attached byAuthInterceptorrather than carried over.A caller that sets
headers.authorizationby hand, rather than lettingAuthInterceptorattach it, no longer has that exact value forwarded across a redirect; the interceptor re-derives the header for the new uri. No in-tree caller that sets the header by hand is on a redirecting path, and those that do set it (webinar,user,support) set the user token, which is what the interceptor attaches. Callers that useoptions.authare unaffected, becauseAuthInterceptorstill returns early for those.For the status code:
HttpStatusInterceptorruns beforeRedirectInterceptoron responses, and already rejects a response of400or above carrying either body unless it is a404. The new condition therefore only changes what happens to responses below400, which are not redirects.Change Type
The following scenarios were tested
yarn workspace @webex/webex-core test:unit— 33 suites, 758 tests passing.Servicesand a realServicesV2catalog, following the pattern added in fix(webex-core): match allowed domains on DNS label boundaries #5144. The realhasAllowedDomains()/isAllowedDomainUrl()are kept rather than stubbed, andwaitForServiceis made to reject so that an allowed domain is the only thing that can authorize the request. Each branch asserts that the header is not forwarded, that a redirect to a uri under an allowed domain is still authorized with the user token, and that a redirect to a uri that is under neither the catalog nor an allowed domain is issued with noauthorizationheader and does not request a token. The options of the request being redirected are asserted to be left untouched.yarn workspace @webex/plugin-meetings test:unit— 3698 passing. Noplugin-meetingschanges; run because it is the largest consumer of the redirecting services.yarn workspace @webex/webex-core test:style— no new findings.The GAI Coding Policy And Copyright Annotation Best Practices
I certified that